package com.sec.android.app.myfiles.thumbnail;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;

import com.sec.android.app.myfiles.info.AppConstants;
import com.sec.android.app.myfiles.info.FileType;
import com.sec.android.app.myfiles.log.Log;
import com.sec.android.app.myfiles.module.abstraction.FileRecord;
import com.sec.android.app.myfiles.util.ExifUtils;
import com.sec.android.app.myfiles.util.GolfUtils;

import java.io.FileDescriptor;
import java.io.FileInputStream;

public class ImageThumbnailImp extends ThumbnailImp {
    /**
     * Constant used to indicate the dimension of mini thumbnail.
     */

    public ImageThumbnailImp(Context context) {
        super(context);
    }

    @Override
    protected boolean isSupport(FileRecord record) {
        return FileType.isImageFileType(record.getFileType());
    }

    @Override
    public Bitmap _createThumbnail(FileRecord record, int thumbnailSize) {
        Bitmap bmp;

        if (record.getFileType() == FileType.GOLF) {
            bmp = createGolfShotThumbnail(record.getFullPath());
        } else {
            bmp = getCenterCropBitmap(record, thumbnailSize);
            if (bmp != null) {
                bmp = getRotatedBitmap(bmp, record);
            } else {
                bmp = ExifUtils.createThumbnailFromEXIF(record, thumbnailSize, thumbnailSize * thumbnailSize);
            }

            bmp = fillTransparentArea(record, bmp);
        }
        return bmp;
    }

    private Bitmap getCenterCropBitmap(FileRecord record, int thumbnailSize) {
        if (record.getSize() > AppConstants.LARGE_IMAGE_SIZE) {
            return null;
        }
        Bitmap bmp = null;
        try (FileInputStream stream = new FileInputStream(record.getFullPath())) {
            FileDescriptor fd = stream.getFD();
            BitmapFactory.Options options = getBmpFactoryOption(fd, thumbnailSize);
            if (options != null) {
                Rect rect = getCenterCropRect(options);
                if (isSupportRegionDecoder(record)) {
                    bmp = BitmapRegionDecoder.newInstance(stream, false).decodeRegion(rect, options);
                } else {
                    bmp = BitmapFactory.decodeFileDescriptor(fd, null, options);
                }
            }
        } catch (Exception e) {
            Log.e(this, "Exception:" + e.toString());
        }
        return bmp;
    }

    private Rect getCenterCropRect(BitmapFactory.Options options) {
        int width = options.outWidth;
        int height = options.outHeight;
        int left, top, right, bottom;
        if (width > height) {
            left = (width - height) / 2;
            top = 0;
            right = left + height;
            bottom = height;
        } else {
            left = 0;
            top = (height - width) / 2;
            right = width;
            bottom = top + width;
        }
        return new Rect(left, top, right, bottom);
    }

    private boolean isSupportRegionDecoder(FileRecord record) {
        int fileType = record.getFileType();
        return fileType == FileType.JPG || fileType == FileType.JPEG || fileType == FileType.PNG;
    }

    private Bitmap getRotatedBitmap(Bitmap oriBmp, FileRecord record) {
        Bitmap ret = oriBmp;
        int degree = ExifUtils.getRotationAngleByExif(ExifUtils.getExif(record.getFullPath()));
        if (degree != 0) {
            ret = ExifUtils.getRotateBitmap(oriBmp, degree);
        }
        return ret;
    }

    private Bitmap fillTransparentArea(FileRecord record, Bitmap oriBmp) {
        Bitmap ret = oriBmp;
        if (oriBmp != null && (record.getFileType() == FileType.PNG || record.getFileType() == FileType.GIF)) {
            ret = Bitmap.createBitmap(ret.getWidth(), ret.getHeight(), ret.getConfig());
            Canvas canvas = new Canvas(ret);
            canvas.drawColor(Color.BLACK);
            canvas.drawBitmap(oriBmp, 0, 0, null);
            if (!oriBmp.isRecycled()) {
                oriBmp.recycle();
            }
        }
        return ret;
    }

    private Bitmap createGolfShotThumbnail(String golfFilePath) {
        String tempFilePath = GolfUtils.getJpgTempFilePath(golfFilePath, false);
        return BitmapFactory.decodeFile(tempFilePath);
    }
}
